package com.axend.aerosense.room.viewmodel;

import android.util.Base64;

import androidx.lifecycle.MutableLiveData;

import com.alibaba.android.arouter.launcher.ARouter;
import com.axend.aerosense.base.bean.BaseBean;
import com.axend.aerosense.base.bean.BaseStringBean;
import com.axend.aerosense.base.impl.IBaseView;
import com.axend.aerosense.base.impl.ILoadDataResult;
import com.axend.aerosense.base.storage.MmkvHelper;
import com.axend.aerosense.base.utils.ByteUtils;
import com.axend.aerosense.base.utils.LogUtils;
import com.axend.aerosense.base.utils.ThreadPoolUtils;
import com.axend.aerosense.base.viewmodel.CustomBaseViewModel;
import com.axend.aerosense.common.UrlApi;
import com.axend.aerosense.common.WsApi;
import com.axend.aerosense.common.config.Gobal;
import com.axend.aerosense.common.router.RouterActivityPath;
import com.axend.aerosense.common.util.JsonUtil;
import com.axend.aerosense.network.EasyHttp;
import com.axend.aerosense.network.cache.model.CacheMode;
import com.axend.aerosense.network.callback.SimpleCallBack;
import com.axend.aerosense.network.exception.ApiException;
import com.axend.aerosense.network.websocket.JWebSocketClient;
import com.axend.aerosense.room.R;
import com.axend.aerosense.room.entity.RadarAddressBean;
import com.axend.aerosense.room.entity.RadarAddressSendBean;
import com.axend.aerosense.room.entity.RoomDoorPositionBean;
import com.blankj.utilcode.util.ToastUtils;


import java.nio.ByteBuffer;


public class RoomSceneLearnIngViewModel extends CustomBaseViewModel<BaseBean> {
    private JWebSocketClient client;
    private MutableLiveData<Float> currentX = new MutableLiveData<>(0.0f);//人的位置
    private MutableLiveData<Float> currentY = new MutableLiveData<>(0.0f);//人的位置
    private MutableLiveData<Boolean> isEndWebSocket = new MutableLiveData<>(false);//webSocket关闭
    private MutableLiveData<Boolean> isSavePoint = new MutableLiveData<>(false);//点保存
    private MutableLiveData<Float> radarWorkDistance = new MutableLiveData<>(0.0f);//雷达工作距离
    private String radarId = "000000000000";
    private final String token;
    private MutableLiveData<Boolean> isReceivePoint = new MutableLiveData<>(false);
    private int startWsWorkCurrent = 0;
    private MutableLiveData<Boolean> failWsWork = new MutableLiveData<>(false);//点保存

    public MutableLiveData<Boolean> getIsExistPointData() {
        return isExistPointData;
    }

    public void setIsExistPointData(MutableLiveData<Boolean> isExistPointData) {
        this.isExistPointData = isExistPointData;
    }

    private MutableLiveData<Boolean> isExistPointData = new MutableLiveData<>(false);


    public MutableLiveData<Boolean> getIsReceivePoint() {
        return isReceivePoint;
    }

    public void setIsReceivePoint(MutableLiveData<Boolean> isReceivePoint) {
        this.isReceivePoint = isReceivePoint;
    }

    public MutableLiveData<Boolean> getFailWsWork() {
        return failWsWork;
    }

    public void setFailWsWork(MutableLiveData<Boolean> failWsWork) {
        this.failWsWork = failWsWork;
    }

    public MutableLiveData<Float> getRadarWorkDistance() {
        return radarWorkDistance;
    }

    public void setRadarWorkDistance(MutableLiveData<Float> radarWorkDistance) {
        this.radarWorkDistance = radarWorkDistance;
    }

    public MutableLiveData<Float> getCurrentX() {
        return currentX;
    }

    public void setCurrentX(MutableLiveData<Float> currentX) {
        this.currentX = currentX;
    }

    public MutableLiveData<Float> getCurrentY() {
        return currentY;
    }

    public void setCurrentY(MutableLiveData<Float> currentY) {
        this.currentY = currentY;
    }

    public String getRadarId() {
        return radarId;
    }

    public void setRadarId(String radarId) {
        this.radarId = radarId;
    }

    public MutableLiveData<Boolean> getIsSavePoint() {
        return isSavePoint;
    }

    public void setIsSavePoint(MutableLiveData<Boolean> isSavePoint) {
        this.isSavePoint = isSavePoint;
    }

    public MutableLiveData<Boolean> getIsEndWebSocket() {
        return isEndWebSocket;
    }

    public void setIsEndWebSocket(MutableLiveData<Boolean> isEndWebSocket) {
        this.isEndWebSocket = isEndWebSocket;
    }

    public RoomSceneLearnIngViewModel(IBaseView baseViewImpl, ILoadDataResult<BaseBean> loadDataResultImpl) {
        super(baseViewImpl, loadDataResultImpl);
        token = MmkvHelper.getInstance().getMmkv().decodeString(Gobal.SAVE_KEY.TOKEN);
    }

    public JWebSocketClient getClient() {
        return client;
    }

    public void setClient(JWebSocketClient client) {
        this.client = client;
    }

    @Override
    public void onLoad() {
        //请求工作范围
        EasyHttp.get(UrlApi.getWorkRangeUrl + radarId)
                .cacheMode(CacheMode.NO_CACHE)
                .execute(new SimpleCallBack<Float>() {
                    @Override
                    public void onError(ApiException e) {
                        e.printStackTrace();
                        loadDataFail(e.getMessage());
                        ToastUtils.showShort(e.getMessage());
                    }

                    @Override
                    public void onSuccess(Float f) {
                        radarWorkDistance.postValue(f);
                        initWebSocket();
                        loadDataSuccess(null);
                    }

                    @Override
                    public void onTokenExpire() {
//                        loadDataFail("");
//                        ARouter.getInstance().build(RouterActivityPath.Login.PAGE_LOGIN_HOME).withBoolean("jumpMainPage", false).greenChannel().navigation();
                    }
                });
//        initWebSocket();
    }

    private void initWebSocket() {

//        URI uri = URI.create("ws://10.8.4.223:8080/position/study?token=" + token + "&radarId=" + radarId);
        client = new JWebSocketClient.Builder(WsApi.getPositionStudyURI(token, radarId), message -> {
            try {
//                    LogUtils.d(message);
                RadarAddressBean obj = JsonUtil.toObject(message, RadarAddressBean.class);
                if (obj.getFunction() == 16) {
                    //[0,0,0,1,0,0,0,0,0,0,0,0]
                    byte[] data = Base64.decode(obj.getData().getBytes(), 0);
//                        LogUtils.d("decoded",decoded);
//                        byte[] data = ByteUtils.hexStringToBytes(obj.getData());
                    ByteBuffer buffer = ByteBuffer.wrap(data);
                    int flag = buffer.getInt();
                    LogUtils.d("flag:", flag);
                    if (flag == 1) {
                        isReceivePoint.postValue(true);
                    }
                    if (isReceivePoint.getValue() != null && !isReceivePoint.getValue()) {//重新发开始学习
                        startWsWork();
                        startWsWorkCurrent++;
                    }
                    if (startWsWorkCurrent > 10 && !isReceivePoint.getValue()) {
                        failWsWork();
                    }
                    if (flag == 2 && isReceivePoint.getValue()) {
                        isExistPointData.postValue(true);
                        float x = buffer.getFloat();
                        float y = buffer.getFloat();
                        if (x != 0 || y != 0) {
                            //当前人的位置
                            currentX.postValue(x);
                            currentY.postValue(y);
//                                LogUtils.d("x:", x);
//                                LogUtils.d("y:", y);
//                                ToastUtils.showShort("x:" + x + "--y:" + y);
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).onError(e->loadDataFail("Failed to connect to webSocket")).connectAfterRun(this::startWsWork).builder();
        client.jConnect();
    }

    //开始学习
    public void startWsWork() {
        LogUtils.d("1111startWsWork:", "1111startWsWork");
        ThreadPoolUtils.getInstance().execute(() -> {
            LogUtils.d("startWsWork:", "startWsWork");
            while (isReceivePoint.getValue() != null && !isReceivePoint.getValue()) {
                RadarAddressSendBean radarAddressSendBean = new RadarAddressSendBean();
                radarAddressSendBean.setFunction(16);
                byte[] data = {0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0};
//      radarAddressBean.setData(ByteUtils.bytesToHexString(data));
                radarAddressSendBean.setData(data);
                client.jSendMsg(JsonUtil.toJson(radarAddressSendBean));
                startWsWorkCurrent++;
                if (startWsWorkCurrent > 10 && !isReceivePoint.getValue()) {
                    isReceivePoint.postValue(true);
                    failWsWork();
                }
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public void endWebSocket(boolean isSavePoint) {
//            结束webSocket连接
        RadarAddressBean radarAddressBean = new RadarAddressBean();
        radarAddressBean.setFunction(16);
        byte[] data = {0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0};
        radarAddressBean.setData(ByteUtils.bytesToHexString(data));
        if (client != null && client.isOpen()) {
            client.jSendMsg(JsonUtil.toJson(radarAddressBean));
            client.closeConnectByUser();
            isEndWebSocket.postValue(true);
        }
        if (isSavePoint) {
            sendLastPoint();
        }
    }

    public void failWsWork() {
        endWebSocket(false);
        failWsWork.postValue(true);
    }

    //发送最后一个点到服务器
    private void sendLastPoint() {
        //把最后的位置发给服务器
        RoomDoorPositionBean roomDoorPositionBean = new RoomDoorPositionBean();
        roomDoorPositionBean.radarId = radarId;
        roomDoorPositionBean.x = currentX.getValue() != null ? currentX.getValue() : 0;
        roomDoorPositionBean.y = currentY.getValue() != null ? currentY.getValue() : 0;

        EasyHttp.post(UrlApi.URL.SavePointResult.getUrl())
                .cacheMode(CacheMode.NO_CACHE)
                .headers("token", token)
                .upJson(JsonUtil.toJson(roomDoorPositionBean))
                .execute(new SimpleCallBack<BaseStringBean>() {
                    @Override
                    public void onError(ApiException e) {
                        loadDataFail(e.getMessage());
                    }

                    @Override
                    public void onSuccess(BaseStringBean baseStringBean) {
                        isSavePoint.postValue(true);
                    }

                    @Override
                    public void onTokenExpire() {
                        loadDataFail("");
                        ToastUtils.showShort(R.string.common_login_first);
                        ARouter.getInstance().build(RouterActivityPath.Login.PAGE_LOGIN_HOME).withBoolean("jumpMainPage", true).greenChannel().navigation();
                    }
                });
    }
}
